/**
 * File: StatisticSummary.java
 * Created by: mhaimel
 * Created on: Mar 24, 2010
 * CVS:  $Id: StatisticSummary.java 1.0 Mar 24, 2010 3:02:15 PM mhaimel Exp $
 */
package uk.ac.ebi.curtain.model.graph.curtain;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author mhaimel
 *
 */
public class StatisticSummary<N extends Number> {
	private final AtomicReference<N> min = new AtomicReference<N>();
	private final AtomicReference<N> max = new AtomicReference<N>();
	private final AtomicReference<Number> sum = new AtomicReference<Number>();
	private final AtomicReference<N> median = new AtomicReference<N>();
	private final AtomicReference<N> q1 = new AtomicReference<N>();
	private final AtomicReference<N> q3 = new AtomicReference<N>();
	private final AtomicReference<N> n50 = new AtomicReference<N>();
	private final AtomicReference<Number> mean = new AtomicReference<Number>();
	private final AtomicLong size = new AtomicLong();
	
	public StatisticSummary(N defaultVal){
		this.min.set(defaultVal);
		this.max.set(defaultVal);
		this.sum.set(defaultVal);
		this.median.set(defaultVal);
		this.q1.set(defaultVal);
		this.q3.set(defaultVal);
		this.n50.set(defaultVal);
		this.mean.set(defaultVal.doubleValue());
		this.size.set(0l);
	}
	
	public StatisticSummary(){
		this.size.set(0l);
	}
	
	/**
	 * 
	 * @return the mean
	 */
	public Number getMean(){
		return this.mean.get();
	}	
	/**
	 * 
	 * @param mean set the mean
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setMean(Number mean) {
		this.mean.set(mean);
		return this;
	}
	
	/**
	 * 
	 * @return the average
	 * @see #getMean()
	 */
	public Number getAverage(){
		return getMean();
	}	
	/**
	 * 
	 * @param average set the average
	 * @return this {@link StatisticSummary}
	 * @see #setMean(Double)
	 */
	public StatisticSummary<N> setAverage(Number avg) {
		return setMean(avg);
	}
	
	/**
	 * @return the min
	 */
	public N getMin() {
		return min.get();
	}
	/**
	 * 
	 * @param min set the min
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setMin(N min) {
		this.min.set(min);
		return this;
	}

	/**
	 * @return the max
	 */
	public N getMax() {
		return max.get();
	}
	/**
	 * 
	 * @param max set the max
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setMax(N max) {
		this.max.set(max);
		return this;
	}

	/**
	 * @return the N50
	 */
	public N getN50() {
		return max.get();
	}
	/**
	 * 
	 * @param n50 set the n50
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setN50(N n50) {
		this.n50.set(n50);
		return this;
	}

	/**
	 * @return the sum
	 */
	public Number getSum() {
		return sum.get();
	}
	
	/**
	 * 
	 * @param sum set the sum
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setSum(Number sum) {
		this.sum.set(sum);
		return this;
	}

	/**
	 * @return the median
	 */
	public N getMedian() {
		return median.get();
	}
	
	/**
	 * 
	 * @param median set the Median
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setMedian(N median) {
		this.median.set(median);
		return this;
	}

	/**
	 * @return the q1
	 */
	public N getQ1() {
		return q1.get();
	}

	/**
	 * 
	 * @param q1 set the q1
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setQ1(N q1) {
		this.q1.set(q1);
		return this;
	}

	/**
	 * @return the q3
	 */
	public N getQ3() {
		return q3.get();
	}

	/**
	 * 
	 * @param q3 set the q3
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setQ3(N q3) {
		this.q3.set(q3);
		return this;
	}

	/**
	 * @return the size
	 */
	public long getSize() {
		return size.get();
	}
	
	/**
	 * 
	 * @param size set the size
	 * @return this {@link StatisticSummary}
	 */
	public StatisticSummary<N> setSize(long size) {
		this.size.set(size);
		return this;
	}
	
	@Override
	public String toString() {
		return new StringBuilder()
		.append("size=")
		.append(getSize())
		.append(";q1=")
		.append(getQ1())
		.append(";median=")
		.append(getMedian())
		.append(";q3=")
		.append(getQ3())
		.append(";avg=")
		.append(getAverage())
		.append(";max=")
		.append(getMax())
		.append(";N50=")
		.append(getN50())	
		.append(";sum=")
		.append(getSum())			
		.toString();
	}
}
